package com.example.fasttalk.client;

import com.example.fasttalk.client.ServerApiEnum;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.function.Consumer;

/**
 * @author SundayLi
 * @date 2023/2/27 15:40
 */
public class SseActuatorBuilder {
  public static SseActuator builder() {
    return new SseActuator();
  }

  public static class SseActuator implements SetServerUrl, SetApi, SetParam {
    String serverUrl;
    ServerApiEnum api;
    String token;
    Consumer<String> executeCallback;

    @Override
    public SetApi serverUrl(String serverUrl) {
      this.serverUrl = serverUrl;
      return this;
    }

    @Override
    public SetParam api(ServerApiEnum api) {
      this.api = api;
      return this;
    }

    public SseActuator then(Consumer<String> function) {
      this.executeCallback = function;
      return this;
    }

    public void execute() {
      HttpClient client = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_1_1)
        .followRedirects(HttpClient.Redirect.NORMAL)
        .connectTimeout(Duration.ofSeconds(20))
        .build();
      HttpRequest.Builder builder = HttpRequest.newBuilder()
        .uri(URI.create(serverUrl + api.getPath() + "?token=" + token))
        .timeout(Duration.ofMinutes(2))
        .header("Content-Type", "text/plain; charset=UTF-8");
      client.sendAsync(builder.GET().build(), HttpResponse.BodyHandlers.ofInputStream())
        .thenApply(HttpResponse::body)
        .thenAccept(inputStream -> {
          String line = "";
          boolean flag = false;
          BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
          try {
            while ((line = reader.readLine()) != null) {
              if (flag) {
                flag = false;
                executeCallback.accept(line.substring(5));
              }
              if ("event:talk_record_text".equals(line.trim())) {
                flag = true;
              }
            }
          } catch (Exception e) {
            // 重连~
            this.execute();
          }
        });
    }

    @Override
    public SseActuator param(String token) {
      this.token = token;
      return this;
    }
  }

  interface SetServerUrl {
    SetApi serverUrl(String serverUrl);
  }

  interface SetApi {
    SetParam api(ServerApiEnum api);
  }

  interface SetParam {
    SseActuator param(String token);
  }
}
